#ifndef __M_ONLINE_H__
#define __M_ONLINE_H__

#include "logger.hpp"
#include <mutex>
#include <unordered_map>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

class online_manager
{
private:
    std::mutex _mutex;                                                     // 保证两个哈希表(共享资源)的线程安全
    std::unordered_map<int, wsserver_t::connection_ptr> _hall_online_user; // 关联游戏大厅中的用户和通信连接
    std::unordered_map<int, wsserver_t::connection_ptr> _room_online_user; // 关联游戏房间中的用户和通信连接
public:
    online_manager() 
    {
        DLOG("在线用户管理模块初始化完毕!");
    }
    ~online_manager() {}
    // websocket连接建立的时候，将用户添加到游戏大厅/房间在线用户管理模块
    void enter_game_hall(int uid, wsserver_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_online_user.insert(std::make_pair(uid, conn));
    }
    void enter_game_room(int uid, wsserver_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_online_user.insert(std::make_pair(uid, conn));
    }
    // websocket连接断开的时候，将用户从游戏大厅/房间在线用户管理模块中移除
    void exit_game_hall(int uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_online_user.erase(uid);
    }
    void exit_game_room(int uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_online_user.erase(uid);
    }
    // 判断当前指定用户是否在游戏大厅/房间中
    bool is_in_game_hall(int uid)
    {
        std::unique_lock<std::mutex> lock(_mutex); //_hall_online_user是共享资源，多线程访问需要加锁保护
        auto it = _hall_online_user.find(uid);
        if (it == _hall_online_user.end()) return false;
        return true;
    }
    bool is_in_game_room(int uid)
    {
        std::unique_lock<std::mutex> lock(_mutex); //_room_online_user是共享资源，多线程访问需要加锁保护
        auto it = _room_online_user.find(uid);
        if (it == _room_online_user.end()) return false;
        return true;
    }
    // 通过用户id在游戏大厅/房间管理模块中获取对应的通信连接
    wsserver_t::connection_ptr get_conn_from_hall(int uid)
    {
        std::unique_lock<std::mutex> lock(_mutex); //_hall_online_user是共享资源，多线程访问需要加锁保护
        auto it = _hall_online_user.find(uid);
        if (it == _hall_online_user.end()) return wsserver_t::connection_ptr();
        return it->second;
    }
    wsserver_t::connection_ptr get_conn_from_room(int uid)
    {
        std::unique_lock<std::mutex> lock(_mutex); //_room_online_user是共享资源，多线程访问需要加锁保护
        auto it = _room_online_user.find(uid);
        if (it == _room_online_user.end()) return wsserver_t::connection_ptr();
        return it->second;   
    }
};
#endif